/**
* Mod Captcha
* implementado por TeNaCiOuS
*/

package com.l2jserver.gameserver.model.AntibotCaptchaSystem;

import gov.nasa.worldwind.formats.dds.DDSConverter;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.concurrent.ScheduledFuture;
import java.util.logging.Logger;

import javax.imageio.ImageIO;

import com.l2jserver.Config;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.idfactory.IdFactory;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.clientpackets.RequestEnchantItem;
import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jserver.gameserver.network.serverpackets.PledgeCrest;
import com.l2jserver.gameserver.skills.AbnormalEffect;


public final class AntibotCaptchaMain
{
	protected static final Logger _log = Logger.getLogger(RequestEnchantItem.class.getName());
	static NpcHtmlMessage adminReply = new NpcHtmlMessage(5);
	public static StringBuilder finalString = new StringBuilder();
	
	public static BufferedImage generateCaptcha(L2PcInstance afectado)
	{
		final Color textColor = new Color(98, 213, 43);
		final Color circleColor = new Color(98, 213, 43);
		final Font textFont = new Font("comic sans ms", Font.BOLD, 24);
		final int charsToPrint = 5;
		final int width = 256;
		final int height = 64;
		final int circlesToDraw = 8;
		final float horizMargin = 20.0f;
		final double rotationRange = 0.7; // this is radians
		final BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		
		final Graphics2D g = (Graphics2D) bufferedImage.getGraphics();
		
		//Draw an oval
		g.setColor(new Color(30, 31, 31));
		g.fillRect(0, 0, width, height);
		
		// lets make some noisey circles
		g.setColor(circleColor);
		for (int i = 0; i < circlesToDraw; i++)
		{
			final int circleRadius = (int) (Math.random() * height / 2.0);
			final int circleX = (int) (Math.random() * width - circleRadius);
			final int circleY = (int) (Math.random() * height - circleRadius);
			g.drawOval(circleX, circleY, circleRadius * 2, circleRadius * 2);
		}
		
		g.setColor(textColor);
		g.setFont(textFont);
		
		final FontMetrics fontMetrics = g.getFontMetrics();
		final int maxAdvance = fontMetrics.getMaxAdvance();
		final int fontHeight = fontMetrics.getHeight();
				
		final float spaceForLetters = -horizMargin * 2 + width;
		final float spacePerChar = spaceForLetters / (charsToPrint - 1.0f);
		
		for (int i = 0; i < charsToPrint; i++)
		{
			final double randomValue = Math.random();
			final int randomIndex = (int) Math.round(randomValue * (Config.TMODS_ANTIBOT_CAPTCHA_ALLOWED_CHARS.length - 1));
			final char characterToShow = Config.TMODS_ANTIBOT_CAPTCHA_ALLOWED_CHARS[randomIndex];
			finalString.append(characterToShow);
			
			// this is a separate canvas used for the character so that
			// we can rotate it independently
			final int charWidth = fontMetrics.charWidth(characterToShow);
			final int charDim = Math.max(maxAdvance, fontHeight);
			final int halfCharDim = charDim / 2;
			
			final BufferedImage charImage = new BufferedImage(charDim, charDim, BufferedImage.TYPE_INT_ARGB);
			final Graphics2D charGraphics = charImage.createGraphics();
			charGraphics.translate(halfCharDim, halfCharDim);
			final double angle = (Math.random() - 0.5) * rotationRange;
			charGraphics.transform(AffineTransform.getRotateInstance(angle));
			charGraphics.translate(-halfCharDim, -halfCharDim);
			charGraphics.setColor(textColor);
			charGraphics.setFont(textFont);
			
			final int charX = (int) (0.5 * charDim - 0.5 * charWidth);
			charGraphics.drawString("" + characterToShow, charX, (charDim - fontMetrics.getAscent()) / 2 + fontMetrics.getAscent());
			
			final float x = horizMargin + spacePerChar * i - charDim / 2.0f;
			final int y = (height - charDim) / 2;
			g.drawImage(charImage, (int) x, y, charDim, charDim, null, null);
			
			charGraphics.dispose();
		}
		
		g.dispose();
		
		//fijando el codigo al afectado
		afectado.setCode(finalString);
		finalString.replace(0, 5, "");
		
		return bufferedImage;
	}
	
	
	public static void SendCaptchaDialog(L2PcInstance activeChar)
	{
		ScheduledFuture<?> CaptchaTimerShedule;
		//Random image file name
		final int imgId = IdFactory.getInstance().getNextId();
		//Convertion from .png to .dds, and crest packed send
		try
		{
			final File captcha = new File("data/captcha/captcha.png");
			ImageIO.write(generateCaptcha(activeChar), "png", captcha);
			final PledgeCrest packet = new PledgeCrest(imgId, DDSConverter.convertToDDS(captcha).array()); //Convertion to DDS where is antybot
			activeChar.sendPacket(packet);
		}
		catch (final Exception e)
		{
			_log.warning(e.getMessage());
		}
		//Paralyze, abnormal effect, invul, html with captcha output and start of the 1 min counter
		activeChar.startAbnormalEffect(AbnormalEffect.REAL_TARGET);
		activeChar.setIsParalyzed(true);
		activeChar.setIsInvul(true);
		adminReply.setHtml("<html><title>Captcha Antibot System</title><body><center>Enter the 5-digits code below and click Confirm.<br><img src=\"Crest.crest_" + Config.SERVER_ID + "_" + imgId + "\" width=256 height=64><br><font color=\"888888\">(There are only english uppercase letters.)</font><br1><font color=\"FF0000\">Tries Left: " + activeChar.getTries() + "</font><br><edit var=\"antibot\" width=110><br><button value=\"Confirm\" action=\"bypass -h voice .antibot $antibot\" width=80 height=26 back=\"L2UI_CT1.Button_DF_Down\" fore=\"L2UI_ct1.button_df\"><br>If you close by mistake this window,<br1>you can re-open it by typing \".captcha\" on Chat.<br1>You have " + String.valueOf(Config.TMODS_ANTIBOT_CAPTCHA_REQUEST_TIME / 60000) + " minutes to answer or you<br1>will get jailed.<br1>You have " + String.valueOf(Config.TMODS_ANTIBOT_CAPTCHA_TRIES) + " tries, if you will<br1>answer wrong to all of them you<br1>will get punished.</center></body></html>");
		activeChar.sendPacket(adminReply);					
		CaptchaTimerShedule = ThreadPoolManager.getInstance().scheduleGeneral(new AntibotCaptchaTimer(activeChar), Config.TMODS_ANTIBOT_CAPTCHA_REQUEST_TIME);
		activeChar.setCaptchaTimmerShedule(CaptchaTimerShedule);
		activeChar.setCodeRight(false);
	}
	
 }